//! Pipit 标准库集成（Rust 实现 + 可选 C 绑定）
//! Pipit 标准库集成
//! 
//! 提供：纯 Rust 的标准库实现（默认），以及在 feature = "use_c_stdlib" 时的 C 绑定声明。



use std::io::{self, Write};
use std::time::{SystemTime, UNIX_EPOCH};
use std::collections::HashMap;
use once_cell::sync::Lazy;

/// 标准库函数集合 - 纯 Rust 实现
pub mod stdlib_functions {
    use super::*;

    pub fn pipit_read_int() -> i32 {
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap_or_default();
        input.trim().parse().unwrap_or(0)
    }

    pub fn pipit_read_float() -> f64 {
        let mut input = String::new();
        io::stdin().read_line(&mut input).unwrap_or_default();
        input.trim().parse().unwrap_or(0.0)
    }

    pub fn pipit_get_time() -> u64 {
        SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap_or_default()
            .as_millis() as u64
    }

    pub fn strdup(s: &str) -> String {
        s.to_string()
    }

    pub fn vsnprintf(buffer: &mut [u8], format: &str, args: &[&str]) -> usize {
        let mut out = format.to_string();
        for a in args.iter() {
            out = out.replacen("%d", a, 1);
            out = out.replacen("%f", a, 1);
            out = out.replacen("%s", a, 1);
        }
        let bytes = out.as_bytes();
        let len = std::cmp::min(buffer.len().saturating_sub(1), bytes.len());
        if len > 0 { buffer[..len].copy_from_slice(&bytes[..len]); }
        if buffer.len() > 0 { buffer[len] = 0; }
        len
    }

    pub fn getcwd() -> String {
        std::env::current_dir()
            .unwrap_or_else(|_| std::path::PathBuf::from("."))
            .to_string_lossy()
            .to_string()
    }

    pub fn rmdir(path: &str) -> bool {
        std::fs::remove_dir(path).is_ok()
    }

    pub fn print_output(s: &str) {
        print!("{}", s);
        io::stdout().flush().unwrap_or_default();
    }

    pub fn print_line(s: &str) {
        println!("{}", s);
    }
}

#[cfg(feature = "use_c_stdlib")]
pub mod c_bindings {
    use std::ffi::{c_char, c_int, c_double};

    // 在Windows上使用动态链接库
    #[cfg(target_os = "windows")]
    #[link(name = "pipit_stdlib", kind = "dylib")]
extern "C" {
        pub fn pipit_read_int() -> c_int;
        pub fn pipit_read_float() -> c_double;
        pub fn pipit_get_time() -> u64;
        pub fn strdup(s: *const c_char) -> *mut c_char;
        pub fn vsnprintf(buffer: *mut c_char, size: usize, format: *const c_char, args: *const c_char) -> c_int;
        pub fn getcwd(buffer: *mut c_char, size: usize) -> *mut c_char;
        pub fn rmdir(path: *const c_char) -> c_int;
    }
    
    // 在非Windows平台上使用静态链接库
    #[cfg(not(target_os = "windows"))]
    #[link(name = "pipit_stdlib", kind = "static")]
extern "C" {
        pub fn pipit_read_int() -> c_int;
        pub fn pipit_read_float() -> c_double;
        pub fn pipit_get_time() -> u64;
        pub fn strdup(s: *const c_char) -> *mut c_char;
        pub fn vsnprintf(buffer: *mut c_char, size: usize, format: *const c_char, args: *const c_char) -> c_int;
        pub fn getcwd(buffer: *mut c_char, size: usize) -> *mut c_char;
        pub fn rmdir(path: *const c_char) -> c_int;
    }
}

pub struct StdlibConfig {
    pub enable_io: bool,
    pub enable_time: bool,
    pub enable_fs: bool,
}

impl Default for StdlibConfig {
    fn default() -> Self { Self { enable_io: true, enable_time: true, enable_fs: true } }
}

pub fn init_stdlib_integration(_config: StdlibConfig) -> Result<(), String> {
    Ok(())
}

// 原生函数适配：定义不捕获环境的函数并注册为 fn(&mut VirtualMachine)
#[cfg(not(feature = "use_c_stdlib"))]
fn native_read_int(vm: &mut crate::vm::VirtualMachine) {
    let v = stdlib_functions::pipit_read_int();
    vm.stack.push(crate::vm::Value::Integer(v));
}

#[cfg(feature = "use_c_stdlib")]
fn native_read_int(vm: &mut crate::vm::VirtualMachine) {
    let v = unsafe { c_bindings::pipit_read_int() };
    vm.stack.push(crate::vm::Value::Integer(v));
}

#[cfg(not(feature = "use_c_stdlib"))]
fn native_read_float(vm: &mut crate::vm::VirtualMachine) {
    let v = stdlib_functions::pipit_read_float();
    vm.stack.push(crate::vm::Value::Float(v));
}

#[cfg(feature = "use_c_stdlib")]
fn native_read_float(vm: &mut crate::vm::VirtualMachine) {
    let v = unsafe { c_bindings::pipit_read_float() };
    vm.stack.push(crate::vm::Value::Float(v));
}

#[cfg(not(feature = "use_c_stdlib"))]
fn native_get_time(vm: &mut crate::vm::VirtualMachine) {
    let t = stdlib_functions::pipit_get_time();
    // 使用Float类型而不是Integer，以避免32位整数溢出
    vm.stack.push(crate::vm::Value::Float(t as f64 / 1000.0));
}

#[cfg(feature = "use_c_stdlib")]
fn native_get_time(vm: &mut crate::vm::VirtualMachine) {
    let t = unsafe { c_bindings::pipit_get_time() };
    // 使用Float类型而不是Integer，以避免32位整数溢出
    vm.stack.push(crate::vm::Value::Float(t as f64 / 1000.0));
}

fn native_print(vm: &mut crate::vm::VirtualMachine) {
    if let Some(v) = vm.stack.pop() {
        match v {
            crate::vm::Value::Integer(i) => print!("{}", i),
            crate::vm::Value::Float(f) => print!("{}", f),
            crate::vm::Value::Boolean(b) => print!("{}", b),
            crate::vm::Value::String(s) => print!("{}", s),
            _ => print!("{:?}", v),
        }
        let _ = std::io::stdout().flush();
    }
}

fn native_println(vm: &mut crate::vm::VirtualMachine) {
    if let Some(v) = vm.stack.pop() {
        match v {
            crate::vm::Value::Integer(i) => println!("{}", i),
            crate::vm::Value::Float(f) => println!("{}", f),
            crate::vm::Value::Boolean(b) => println!("{}", b),
            crate::vm::Value::String(s) => println!("{}", s),
            _ => println!("{:?}", v),
        }
    }
}

// 为其他标准库函数创建特定的原生实现
fn native_strdup(vm: &mut crate::vm::VirtualMachine) {
    if let Some(crate::vm::Value::String(s)) = vm.stack.pop() {
        vm.stack.push(crate::vm::Value::String(s.clone()));
    } else {
        vm.stack.push(crate::vm::Value::Null);
    }
}

fn native_vsnprintf(vm: &mut crate::vm::VirtualMachine) {
    // 简化实现，实际应该更复杂
    vm.stack.push(crate::vm::Value::Integer(0));
}

fn native_getcwd(vm: &mut crate::vm::VirtualMachine) {
    let cwd = std::env::current_dir()
        .unwrap_or_else(|_| std::path::PathBuf::from("."))
        .to_string_lossy()
        .to_string();
    vm.stack.push(crate::vm::Value::String(cwd));
}

fn native_rmdir(vm: &mut crate::vm::VirtualMachine) {
    if let Some(crate::vm::Value::String(path)) = vm.stack.pop() {
        let success = std::fs::remove_dir(&path).is_ok();
        vm.stack.push(crate::vm::Value::Boolean(success));
    } else {
        vm.stack.push(crate::vm::Value::Boolean(false));
    }
}

// 调试模式配置 - 可以通过环境变量或编译标志设置
const ENABLE_DEBUG_OUTPUT: bool = false;

/// 通用原生函数实现 - 用于处理没有特定实现的函数
fn native_generic(vm: &mut crate::vm::VirtualMachine) {
    // 这个函数是一个通用的占位符实现
    // 简单地打印一条消息，表示函数被调用
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("Generic native function called");
    }
    
    // 默认返回一个空值
    vm.stack.push(crate::vm::Value::Null);
}

// 编译时的函数名称到函数实现的映射
// 使用once_cell创建一个线程安全的懒加载HashMap
static NATIVE_FUNCTION_MAP: Lazy<HashMap<&'static str, fn(&mut crate::vm::VirtualMachine)>> = Lazy::new(|| {
    let mut map = HashMap::new();
    
    // 注册输入相关函数
    map.insert("read_int", native_read_int as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_read_int", native_read_int as fn(&mut crate::vm::VirtualMachine));
    map.insert("read_float", native_read_float as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_read_float", native_read_float as fn(&mut crate::vm::VirtualMachine));
    
    // 注册时间相关函数
    map.insert("get_time", native_get_time as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_get_time", native_get_time as fn(&mut crate::vm::VirtualMachine));
    
    // 注册输出相关函数
    map.insert("print", native_print as fn(&mut crate::vm::VirtualMachine));
    map.insert("println", native_println as fn(&mut crate::vm::VirtualMachine));
    
    // 注册文件系统相关函数
    map.insert("getcwd", native_getcwd as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_getcwd", native_getcwd as fn(&mut crate::vm::VirtualMachine));
    map.insert("rmdir", native_rmdir as fn(&mut crate::vm::VirtualMachine));
    
    // 注册字符串相关函数
    map.insert("strdup", native_strdup as fn(&mut crate::vm::VirtualMachine));
    map.insert("vsnprintf", native_vsnprintf as fn(&mut crate::vm::VirtualMachine));
    
    // 注册其他常用标准库函数 - 添加它们的短名称和带前缀的别名
    // IO模块函数
    map.insert("pipit_fopen", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_fclose", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_fread", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_fwrite", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_feof", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_file_size", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_read_file", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_write_file", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_file_exists", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_remove_file", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_rename_file", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_mkdir", native_generic as fn(&mut crate::vm::VirtualMachine));
    
    // Math模块函数 - 添加短名称和带前缀的别名
    map.insert("add", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_add", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("subtract", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_subtract", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("multiply", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_multiply", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("divide", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_divide", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("modulo", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_modulo", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("power", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_power", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("sqrt", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_sqrt", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("abs", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_abs", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("max", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_max", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("min", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_min", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("random", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_random", native_generic as fn(&mut crate::vm::VirtualMachine));
    
    // String模块函数
    map.insert("string_length", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_string_length", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("string_concat", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_string_concat", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("string_to_upper", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_string_to_upper", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("string_to_lower", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_string_to_lower", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("string_compare", native_generic as fn(&mut crate::vm::VirtualMachine));
    map.insert("pipit_string_compare", native_generic as fn(&mut crate::vm::VirtualMachine));
    
    // 返回填充好的映射
    map
});

/// 将标准库函数注册到虚拟机
pub fn register_stdlib_functions(vm: &mut crate::vm::VirtualMachine) {
    // 添加完整的调试输出
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] register_stdlib_functions 开始执行");
    }
    
    // 检查NATIVE_FUNCTION_MAP中get_time的存在性
    let has_get_time = NATIVE_FUNCTION_MAP.contains_key("get_time");
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] NATIVE_FUNCTION_MAP 包含 get_time: {}", has_get_time);
    }
    
    // 打印NATIVE_FUNCTION_MAP的大小
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] NATIVE_FUNCTION_MAP 大小: {}", NATIVE_FUNCTION_MAP.len());
    }
    
    // 从编译时缓存中注册所有已有的特定实现
    // 这确保了所有在编译时定义的函数在运行时都能被正确调用
    let mut registered_count = 0;
    for (name, func) in NATIVE_FUNCTION_MAP.iter() {
        vm.register_native_function(name.to_string(), *func);
        registered_count += 1;
        
        // 为关键函数添加额外的调试输出
        if ENABLE_DEBUG_OUTPUT && (name == &"get_time" || name == &"pipit_get_time") {
            eprintln!("[Pipit调试] 已注册关键函数: {}", name);
        }
    }
    
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] 从NATIVE_FUNCTION_MAP注册了 {} 个函数", registered_count);
    }
    
    // 检查get_time是否已成功注册
    if ENABLE_DEBUG_OUTPUT {
        if vm.native_functions.contains_key("get_time") {
            eprintln!("[Pipit调试] ✓ get_time 已成功注册到虚拟机");
        } else {
            eprintln!("[Pipit调试] ✗ WARNING: get_time 未注册到虚拟机");
        }
    }
    
    // 为所有可能的标准库函数名（包括短名称和带前缀的别名）注册通用实现
    // 这确保了即使编译器没有识别到的函数，在运行时也能被处理
    let registry = &crate::stdlib_registry::GLOBAL_STDLIB_REGISTRY;
    let registry_functions = registry.get_all_functions();
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] GLOBAL_STDLIB_REGISTRY 包含 {} 个函数", registry_functions.len());
    }
    
    let mut generic_count = 0;
    for func_name in registry_functions {
        // 只注册尚未注册的函数
        if !vm.native_functions.contains_key(func_name) {
            vm.register_native_function(func_name.clone(), native_generic);
            generic_count += 1;
        }
    }
    
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] 从GLOBAL_STDLIB_REGISTRY注册了 {} 个通用实现", generic_count);
    }
    
    // 动态生成并注册所有函数的别名
    // 这确保了所有函数都有短名称和带前缀的版本
    
    // 先收集所有函数名，避免在遍历过程中修改vm
    let all_func_names: Vec<String> = vm.native_functions.keys().cloned().collect();
    
    let mut alias_pairs = Vec::new();
    
    // 首先，收集所有以"pipit_"开头的函数，为它们创建短名称别名
    for func_name in &all_func_names {
        if func_name.starts_with("pipit_") {
            let short_name = &func_name[6..]; // 去掉"pipit_"前缀
            alias_pairs.push((short_name.to_string(), func_name.clone()));
        } else if !func_name.starts_with("pipit_") {
            // 同时，为短名称函数创建带前缀的版本
            let full_name = format!("pipit_{}", func_name);
            alias_pairs.push((func_name.clone(), full_name));
        }
    }
    
    // 去重，避免重复处理
    alias_pairs.sort();
    alias_pairs.dedup();
    
    let mut alias_count = 0;
    for (short_name, full_name) in alias_pairs {
        // 确保两个方向的别名都被注册
        if vm.native_functions.contains_key(&short_name) && !vm.native_functions.contains_key(&full_name) {
            if let Some(func) = vm.native_functions.get(&short_name) {
                vm.register_native_function(full_name.clone(), *func);
                alias_count += 1;
                
                if ENABLE_DEBUG_OUTPUT && (short_name == "get_time" || full_name.contains("get_time")) {
                    eprintln!("[Pipit调试] 注册别名: {} -> {}", short_name, full_name);
                }
            }
        }
        
        if vm.native_functions.contains_key(&full_name) && !vm.native_functions.contains_key(&short_name) {
            if let Some(func) = vm.native_functions.get(&full_name) {
                vm.register_native_function(short_name.clone(), *func);
                alias_count += 1;
                
                if ENABLE_DEBUG_OUTPUT && (full_name.contains("get_time") || short_name == "get_time") {
                    eprintln!("[Pipit调试] 注册别名: {} -> {}", full_name, short_name);
                }
            }
        }
    }
    
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] 注册了 {} 个别名函数", alias_count);
    }
    
    // 最终检查注册状态
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] 虚拟机中总共注册了 {} 个函数", vm.native_functions.len());
    }
    
    // 再次检查get_time的注册状态
    if ENABLE_DEBUG_OUTPUT {
        if vm.native_functions.contains_key("get_time") {
            eprintln!("[Pipit调试] ✓ 最终确认: get_time 函数已成功注册到虚拟机");
        } else {
            eprintln!("[Pipit调试] ✗ 错误: get_time 函数未注册到虚拟机");
        }
    }
    
    // 检查pipit_get_time的注册状态
    if ENABLE_DEBUG_OUTPUT {
        if vm.native_functions.contains_key("pipit_get_time") {
            eprintln!("[Pipit调试] ✓ pipit_get_time 函数已成功注册到虚拟机");
        } else {
            eprintln!("[Pipit调试] ✗ 错误: pipit_get_time 函数未注册到虚拟机");
        }
    }
    
    if ENABLE_DEBUG_OUTPUT {
        eprintln!("[Pipit调试] register_stdlib_functions 执行完毕");
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_stdlib_functions() {
        let config = StdlibConfig::default();
        assert!(init_stdlib_integration(config).is_ok());
        let _ = stdlib_functions::pipit_get_time();
        stdlib_functions::print_output("测试输出");
    }
}